package com.spzx.product.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.common.core.utils.bean.BeanUtils;
import com.spzx.product.domain.Category;
import com.spzx.product.domain.vo.CategoryExcelVo;
import com.spzx.product.listener.ExcelCategoryListener;
import com.spzx.product.mapper.CategoryMapper;
import com.spzx.product.service.CategoryService;
import io.micrometer.core.instrument.binder.BaseUnits;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category>
        implements CategoryService {

    @Override
    public List<Category> listTree(Long id) {
        //调用mapper
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getParentId, id);
        List<Category> list = baseMapper.selectList(queryWrapper);

        //list集合遍历
        list.stream().forEach(category -> {
            LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Category::getParentId, category.getId());
            Long count = baseMapper.selectCount(wrapper);
            if (count > 0) {
                category.setHasChildren(true);
            } else {
                category.setHasChildren(false);
            }
        });
        return list;
    }

    //根据当前第三层分类id，获取第二层和第一层分类id
    @Override
    public List<Long> getAllCategoryById(Long categoryId) {
        List<Long> list = new ArrayList<>();
        // 3 2 1  ==  1 2 3
        List<Category> categoryList = this.getParentCategory(categoryId, new ArrayList<Category>());
        int size = categoryList.size();
        for (int i = size; i > 0; i--) {
            Category category = categoryList.get(i - 1);
            Long id = category.getId();
            list.add(id);
        }
        return list;
    }

    @Override
    public void export(HttpServletResponse response) {
        try {
            //1 设置下载响应头信息 Content-disposition
            // 设置响应结果类型  mime类型
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");

            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("分类数据", "UTF-8");

            //下载过程
            //如果实现下载，首先基于response对象，设置响应头信息
            // 响应头Content-disposition，文件以下载方式打开
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

            //2 调用方法查询数据库获取所有分类list集合
            List<Category> list = baseMapper.selectList(null);

            //List<Category>  ---> List<CategoryExcelVo>
            List<CategoryExcelVo> listVo = list.stream().map(category -> {
                CategoryExcelVo categoryExcelVo = new CategoryExcelVo();
                BeanUtils.copyProperties(category, categoryExcelVo);
                return categoryExcelVo;
            }).collect(Collectors.toList());
            //3 调用EasyExcel方法实现写操作，把数据库表数据写到Excel表格里面
            EasyExcel.write(response.getOutputStream(), CategoryExcelVo.class).sheet("牛马一号").doWrite(listVo);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    //导入  不用监听器的方式
    @Override
    public void importData(MultipartFile file) {//规定形参名必须是file
        try {
            //读取Excel中的数据
            List<CategoryExcelVo> categoryExcelVoList = EasyExcel.read(file.getInputStream())
                    .head(CategoryExcelVo.class)
                    .sheet()
                    .doReadSync();
            //List<CategoryExcelVo> ---->>  List<Category>
            List<Category> collect = list().stream().map(CategoryExcelVo -> {
                Category category = new Category();
                BeanUtils.copyProperties(CategoryExcelVo, category);
                return category;
            }).collect(Collectors.toList());
            //读取到List集合,把list集合添加到数据表中
            this.saveBatch(collect);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //带监听器读写法
    public void importData1(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream())
                    .head(CategoryExcelVo.class)
                    .sheet()
                    .registerReadListener(new ExcelCategoryListener(this))
                    .doRead();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    //  1 2 3
//当前 3
    private List<Category> getParentCategory(Long categoryId, ArrayList<Category> categoryList) {
        //递归
        while (categoryId > 0) {
            //获取当前分类id对应分类数据
            LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Category::getId, categoryId);
            Category category = baseMapper.selectOne(wrapper);

            categoryList.add(category);

            return getParentCategory(category.getParentId(), categoryList);
        }
        return categoryList;
    }
}